-
Notifications
You must be signed in to change notification settings - Fork 240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generic property package: Using constraints to define state variables #1554
Conversation
I'm having degree-of-freedom issues with unfixing |
@alma-walmsley My first reaction to this is that you are opening a huge can of worms with potential edge cases - what happens if someone else had a different know input and constraint? The way I would suggest doing this (and the way the framework was generally built) is that the constraint on |
It is interesting that you suggest applying constraints at the flowsheet level. This is what we were initially doing, but since adding constraints directly to the state block instead, we have been able to solve a lot more consistently. If constraints can be applied at the state block level, this gives us "perfect" initialization and means the flowsheet can be solved in very few iterations. I think this is better because it breaks the problem into smaller subproblems - rather than adding all the complexity at the flowsheet level, which heavily relies on good guesses for the state variables. Relying on user guesses for state variables such as enthalpy (which the user may not know), or using the defaults from the property package, can cause both problems in initialization as well as set the flowsheet solve up to fail when applying constraints. I am aware that this has probably not been the approach when developing unit models. For example, the heat exchanger initialization routine fixes I tend to agree that the code in this PR isn't the best, and feels like a "hack" more than anything. But I think that long term, the state block constraints approach is the best solution to ensure consistent solving without relying too much on user-guesses. We do this with a custom state block (inheriting from |
So, the underlying issue here is that the initialization routines were built on the assumption that the model would be square if/when all the input conditions were fixed. Thus, the routines work by fixing all the inlet states and the working through the problem. By adding additional constraints to the unit model however, this breaks that assumptions and thus all the initialization routines would fail. When you say "but since adding constraints directly to the state block instead, we have been able to solve a lot more consistently", what were the issues you were seeing previously? This sounds like it would be a case of your initial guess was not very good - for the case of fixing flow_mass instead of flow_mol, that sounds like you need a flowsheet level mini-routine that would handle this conversion. Additionally, if you are not doing it already, I would:
In fact, I just thought of what might be the correct solution: these additional constraints should be done as a plug-in to the unit model (similar to how costing is (should?) be implemented). Basically, a plug-in is a sub-model that can be attached to a unit model which comes with its own sub-routine for initialization. The new General Hierarchical Initializer already contains code that should handle the plug-in automatically (it will initialize the main unit model, and then call the plug-in initialization - note this is not heavily tested so might have some bugs). |
Correct, and the approach we are using is an attempt to manage both of these issues. The unit model starts by initializing the control volume which first initializes the inlet state. If we follow the traditional approach of requiring all the state variables to be fixed:
Instead of fixing all the inlet state vars, equality constraint(s) are added to the inlet instead. We still have a square model because each added constraint is accompanied by unfixing one of the state variables. For example, we could fix Applying constraints at the state block level:
I am aware that some of the unit model initialization routines will not like the use of constraints (I mentioned heat exchanger above). I think we can get around this problem by:
Since we're managing unit model initialization (within sequential decomposition) and state block initialization (with our extended state block) we can handle this all on our end. It just requires some support for initializing a state block with constraints instead of state vars. |
This is the key point here:
This is a valid approach, but you are basically invaliding the core assumption that all initialisation was built on, thus if you want this to be a general implementation you are effectively looking to rebuild the entire initialization infrastructure. Speaking from experience, that is a lot of work to implement, and even more to test, so just make sure you are aware of what you are getting yourself into if you go down this route. However, as I mentioned in another comment somewhere - take a look at the hierarchical |
@bertkdowns thoughts? |
Based on our discussion today I am closing this PR, and we will have to come up with another solution to resolve this sort of problem. Thanks for everyone's input! |
Fixes # .
Summary/Motivation:
As part of Ahuora we are using the generic property package framework to build custom property packages.
The code looks something like this:
Suppose that we know the value for
flow_mass
and want to use that instead. We can do this using aConstraint
:However, this ends up running into issues during initialization:
flow_mol
gets fixed anyway, and the block becomes over-defined. However, we are able to prevent this by setting the kwargstate_vars_fixed=True
, which means initialization will skip trying to fix the state variables (and just check for 0 degrees of freedom). So this is not an issue at this stage.flow_mass_constraint
gets deactivated during the "Bubble, dew, and critical point initialization" step (which is fine), but needs to be activated for the "Phase equilibrium initialization" step, to ensure 0 degrees of freedom.The specific error I get is
Changes proposed in this PR:
flow_mass_constraint
(or other constraints as needed) before the "Phase equilibrium initialization" step. This is done by "tagging" the constraint withdefining_state_var = True
to indicate that this constraint defines a state variable, and should be activated.For example,
I added this check to both the
_GenericStateBlock
andModularPropertiesInitializer
initialize methods. I am not too sure how theModularPropertiesInitializer
class is used (seems to be the same logic) but I assume the code fits in both.Comments on this approach would be useful.
Legal Acknowledgement
By contributing to this software project, I agree to the following terms and conditions for my contribution: